package logger.sd.server;

import java.io.IOException;
import java.util.Stack;

import logger.sd.util.AbstractLogger;

import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;

/**
 * Classe ServerLogger
 * 
 * Singleton
 * 
 * A classe serve como um Facade para a API de log.
 * 
 * Esta classe presta servico de loggging para o Servidor
 * 
 * @author Wendell
 * 
 */
@SuppressWarnings("rawtypes")
public class LogWriter extends AbstractLogger {

	private static AbstractLogger instance = null;
	private static Logger logger;
	private static Stack<Class> names = new Stack<Class>();

	private ServerConfiguration config;

	/**
	 * Construtor privado: Singleton
	 */
	
	private LogWriter(Class clazz, ServerConfiguration config) {
		this.config = config;
		names.push(clazz);
		initLog();
	}

	/**
	 * Retorna a instancia do log
	 * 
	 * @return Instancia do Logger do servidor
	 */
	public static LogWriter getInstance(Class clazz, 
			ServerConfiguration config) {
		if (instance == null) {
			instance = new LogWriter(clazz, config);
		}
		return (LogWriter) instance;
	}
	
	/**
	 * Retorna a instancia do log
	 * 
	 * @return Instancia do Logger do servidor
	 */
	public static LogWriter getInstance(Class clazz) {
		if (instance == null) {
			instance = new LogWriter(clazz, new ServerConfiguration());
		}
		return (LogWriter) instance;
	}

	/**
	 * Escreve no log
	 * 
	 * @param level
	 *            Nivel de log
	 * @param message
	 *            Mensagem que sera enviada
	 * @param t
	 *            Exception
	 */
	public void log(Level level, String message) {
		logger.log(level, message);
	}

	/**
	 * Configura e inicializa o Log
	 * 
	 * @exception IOException
	 * 
	 */
	private void initLog() {

		// Instancia o logger onde o servidor vai escrever as
		// mensagens do cliente.
		logger = Logger.getLogger(names.lastElement());

		// Por padrao eh esse, mas o cliente pode mudar...
		logger.setLevel(Level.toLevel(config.getLevel()));

		PatternLayout layout = new PatternLayout("%p: %m\n");

		try {
			ConsoleAppender consoleAppender = new ConsoleAppender(layout);
			Appender fileAppender = new FileAppender(layout,
					config.getLogFilename());

			logger.addAppender(fileAppender);
			logger.addAppender(consoleAppender);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Muda o Level do logger
	 * 
	 * @param level
	 *            Nivel do log
	 */
	public void setLevel(Level level) {
		logger.setLevel(level);
	}

}
